package artid.com.arttogoa.view;

import java.util.ArrayList;
import java.util.List;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import artid.com.arttogoa.R;
import artid.com.arttogoa.parser.PostionPoint;
import artid.com.arttogoa.util.NetUtils;
import artid.com.arttogoa.util.PanelClickListener;

public class CounterView extends View {
	private static final String TAG = "Browse";
	/** 画笔 */
	private Paint mPaint;
	/** 数字画笔 */
	private Paint paint;
	private Context context;
	/** 是否可编辑 */
	private boolean is_Editable = false;
	/** 第一次触摸时的位置 */
	private PointF start = new PointF();
	/** 最后一次触摸时的位置 */
	private PointF end = new PointF();
	/** 地图中心 */
	private PointF mapCenter = new PointF();
	/** 屏幕中心 */
	private PointF screenCenter = new PointF();
	/** 是否是移动中 */
	private boolean move = true;

	/** 存放标记坐标点的集合 */
	private List<PostionPoint> pointData = new ArrayList<PostionPoint>();
	/** 存放标点矩阵的集合 */
	private List<Matrix> oldMatrix = new ArrayList<Matrix>();
	/** 存放标点矩阵坐标的集合 */
	private List<PointF> oldPointF = new ArrayList<PointF>();
	/** 未确定标注点 */
	private Bitmap b;
	/** 以确定标注点 */
	private Bitmap b2;
	/***
	 * touch 事件
	 */
	private float mLastMotionX, mLastMotionY;
	/** 长按的runnable */
	private LongPressedThread mLongPressRunnable;
	/** 移动的阈值 */
	private static final int TOUCH_SLOP = 20;
	/** 存放点击、长按的线程 */
	private Handler mBaseHandler = new Handler();
	/** 长按触发时间 */
	private static final long LONG_PRESS_TIME = 700;
	/** 是否是第一次 */
	private boolean bb = true;

	public CounterView(Context context, AttributeSet attrs) {
		super(context, attrs);
		mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
		this.context = context;
		/** 添加所需要在位置画的点 */
		b = BitmapFactory.decodeResource(getResources(),
				R.drawable.ico_zhunxing);
		b2 = BitmapFactory.decodeResource(getResources(), R.drawable.ico_toumingread);
		paint = new Paint(Paint.ANTI_ALIAS_FLAG);
		paint.setTextSize(NetUtils.dip2px(context, 16));
		paint.setColor(Color.WHITE);
		paint.setTextAlign(Paint.Align.CENTER);
		paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
	}

	private Bitmap bmp = null;
	/** 记录move时的矩阵位置，用于up */
	private Matrix currentMatrix = null;
	/** 监听标点 */
	PanelClickListener panelClickListener;
	/** 图片类型 */
	private int imageType = 1;
	/** 小图片 */
	private final int IMAGE_SMALL = 1;
	/** 大图片 */
	private final int IMAGE_LARGE = 2;
	/** 长图片 */
	private final int IMAGE_LONG = 3;
	/** 高图片 */
	private final int IMAGE_HIGH = 4;

	/**
	 * 初始化函数
	 * 
	 * @param bmp
	 *            需要操作的大图
	 * @param mapCenter
	 *            地图中心坐标点
	 * @param screenCenter
	 *            屏幕中心坐标点
	 */
	public void setImageBitmap(Bitmap bmp, PointF mapCenter, PointF screenCenter) {
		// TODO Auto-generated method stub
		this.bmp = bmp;
		if (mapCenter == null)
			this.mapCenter = mapCenter;
		this.screenCenter = screenCenter;
		mapCenter.set(0, 0);
		setImageType();
		invalidate();
	} 

	/**
	 * @param pointData2
	 */
	public void setInitPointData(Bitmap bmp, PointF mapCenter,
			PointF screenCenter, List<PostionPoint> pointData2) {
		// TODO Auto-generated method stub
		this.bmp = bmp;
		System.out.println("有微观图");
		if (mapCenter == null)
			this.mapCenter = mapCenter;
		this.screenCenter = screenCenter;
		this.pointData = pointData2;
		for (int i = 0; i < pointData.size(); i++) {
			Matrix matrix = new Matrix();
			float xi = mapCenter.x - bmp.getWidth() / 2
					+ pointData.get(i).getPointX() - b2.getWidth() / 2;
			float yi = mapCenter.y - bmp.getHeight() / 2
					+ pointData.get(i).getPointY() - b2.getHeight() / 2;
			matrix.postTranslate(xi, yi);
			oldMatrix.add(matrix);
			oldPointF.add(new PointF(xi, yi));
		}
		setImageType();
		invalidate();

	}

	public void setImageType() {
		int w = bmp.getWidth();
		int h = bmp.getHeight();
		int sw = (int) screenCenter.x * 2;
		int sh = (int) screenCenter.y * 2;
		if (w < sw && h < sh)
			imageType = IMAGE_SMALL;
		else if (w > sw && h > sh)
			imageType = IMAGE_LARGE;
		else if (w < sw && h > sh)
			imageType = IMAGE_HIGH;
		else if (w > sw && h < sh)
			imageType = IMAGE_LONG;
	}

	@SuppressLint("DrawAllocation")
	@Override
	protected void onDraw(Canvas canvas) {
		System.out.println("onDraw");
		super.onDraw(canvas);
		if (bmp != null) {
			Matrix matrix = new Matrix();
			// matrix.setScale(rate, rate, bmp.getWidth() / 2, bmp.getHeight() /
			// 2);
			/** 如果不是移动中（up） */
			if (!move) {
				System.out.println("up");
				System.out.println("h=" + bmp.getHeight() + ",w="
						+ bmp.getWidth());
				/** 如果不是移动中则加载之前的矩阵位置 */
				canvas.drawBitmap(bmp, currentMatrix, mPaint);
				/** 标注坐标 */
				if (pointData.size() == 0) {
					return;
				}

				/** 同上 */
				for (int i = 0; i < pointData.size(); i++) {
					if (pointData.get(i).getPointX() < 0) {
						Matrix matrix1 = new Matrix();
						matrix1.postTranslate(
								oldPointF.get(i).x + b2.getWidth() / 2
										- b.getWidth() / 2, oldPointF.get(i).y
										+ b2.getWidth() / 2 - b.getHeight() / 2);
						canvas.drawBitmap(b, matrix1, mPaint);
					} else {
						canvas.drawBitmap(b2, oldMatrix.get(i), mPaint);
						canvas.drawText("" + (i + 1),
								oldPointF.get(i).x + b2.getWidth() / 2,
								oldPointF.get(i).y + b2.getHeight() / 2
										+ NetUtils.dip2px(context, 12) / 2,
								paint);
					}
				}
			} else {
				/**
				 * 移动之后矩阵采图平移位置
				 */
				float x = mapCenter.x + (end.x - start.x) - bmp.getWidth() / 2;
				float y = mapCenter.y + (end.y - start.y) - bmp.getHeight() / 2;

				if (imageType == IMAGE_SMALL) {
					matrix.postTranslate(screenCenter.x - bmp.getWidth() / 2,
							screenCenter.y - bmp.getHeight() / 2);
					currentMatrix = matrix;
				} else if (imageType == IMAGE_LARGE && bb) {
					Matrix m = new Matrix();
					m.postTranslate(0, 0);
					currentMatrix = m;
					mapCenter.set(bmp.getWidth(), bmp.getHeight());
					matrix.postTranslate(0, 0);
				} else if (imageType == IMAGE_LARGE && !bb) {
					matrix.postTranslate(x, y);
					currentMatrix = matrix;
					canvas.drawBitmap(bmp, matrix, mPaint);
				} else if (imageType == IMAGE_LONG) {
					matrix.postTranslate(x, screenCenter.y - bmp.getHeight()
							/ 2);
					currentMatrix = matrix;
				} else if (imageType == IMAGE_HIGH) {
					matrix.postTranslate(screenCenter.x - bmp.getWidth() / 2, y);
					currentMatrix = matrix;
				}
				System.out
						.println("x="
								+ (mapCenter.x + (end.x - start.x) - bmp
										.getWidth() / 2)
								+ "......y="
								+ (mapCenter.y + (end.y - start.y) - bmp
										.getHeight() / 2));
				/**
				 * 记录矩阵
				 */
				// if (bb) {/** 如果是第一次进入，需要初始化 */
				// Matrix m = new Matrix();
				// m.postTranslate(0, 0);
				// currentMatrix = m;
				// mapCenter.set(bmp.getWidth(), bmp.getHeight());
				// canvas.drawBitmap(bmp, m, mPaint);
				// } else {
				
				canvas.drawBitmap(bmp, matrix, mPaint);
				// }
				// currentMatrix = matrix;
				// canvas.drawBitmap(bmp, matrix, mPaint);
				/** 标注坐标 */
				if (pointData.size() == 0) {
					return;
				}
				/** 画标注点 */
				for (int i = 0; i < pointData.size(); i++) {
					Matrix matrix1 = new Matrix();
					float xi = mapCenter.x + (end.x - start.x) - bmp.getWidth()
							/ 2 + pointData.get(i).getPointX() - b2.getWidth()
							/ 2;
					float yi = mapCenter.y + (end.y - start.y)
							- bmp.getHeight() / 2
							+ pointData.get(i).getPointY() - b2.getHeight() / 2;
					matrix1.postTranslate(xi, yi);
					oldMatrix.set(i, matrix1);
					oldPointF.set(i, new PointF(xi, yi));
					
					canvas.drawBitmap(b2, matrix1, mPaint);
					canvas.drawText("" + (i + 1), xi + b2.getWidth() / 2, yi
							+ b2.getHeight() / 2 + NetUtils.dip2px(context, 12)
							/ 2, paint);
				}
			}

		}
	}

	public List<PostionPoint> getPointData() {
		return pointData;
	}

	public void setPointData(List<PostionPoint> pointData) {
		is_Editable = true;
		this.pointData = pointData;
		for (int i = 0; i < pointData.size(); i++) {
			System.out.println("x=" + pointData.get(i).getPointX() + ",y="
					+ pointData.get(i).getPointY());
			System.out.println("x=" + oldPointF.get(i).x + ",y="
					+ oldPointF.get(i).y);
		}
		// invalidate();
	}

	public void deletePointData(int index) {
		is_Editable = true;
		pointData.remove(index);
		oldMatrix.remove(index);
		oldPointF.remove(index);
		invalidate();
	}

	/**
	 * 模式 NONE：无 DRAG：拖拽. ZOOM:缩放
	 * 
	 * @author zhangjia
	 * 
	 */
	private enum MODE {
		NONE, DRAG, ZOOM

	};

	private MODE mode = MODE.NONE;// 默认模式

	/** 控制图片的可编辑性 **/
	public void setis_Editable(boolean is_Editable) {
		this.is_Editable = is_Editable;
	}

	public boolean getis_Editable() {
		return this.is_Editable;
	}

	public class LongPressedThread implements Runnable {
		@Override
		public void run() {
			/** 这里处理长按事件 */
			float x = bmp.getWidth() / 2 - mapCenter.x + mLastMotionX;
			float y = bmp.getHeight() / 2 - mapCenter.y + mLastMotionY;
			PostionPoint Point = new PostionPoint((int) -x, (int) -y);
			pointData.add(Point);
			Matrix matrix = new Matrix();
			float xi = mapCenter.x + (end.x - start.x) - bmp.getWidth() / 2 + x
					- b2.getWidth() / 2;
			float yi = mapCenter.y + (end.y - start.y) - bmp.getHeight() / 2
					+ y - b2.getHeight() / 2;
			matrix.postTranslate(xi, yi);
			oldMatrix.add(matrix);
			oldPointF.add(new PointF(xi, yi));

			invalidate();
			is_Editable = false;
			panelClickListener.onClick(Point, pointData.size() - 1);
			// Toast.makeText(
			// context,
			// "X==" + mLastMotionX + ",Y==" + mLastMotionY
			// + ",mapCenter.x==" + mapCenter.x + ",mapCenter.y=="
			// + mapCenter.y, 2).show();
		}
	}

	@SuppressLint("ClickableViewAccessibility")
	@Override
	public boolean onTouchEvent(MotionEvent event) {

		/** 处理单点触摸 **/
		if (is_Editable == true) {
			switch (event.getAction() & MotionEvent.ACTION_MASK) {
			/** 手指压下屏幕 */
			case MotionEvent.ACTION_DOWN:
				System.out.println("DOWN");
				/** 创建长按监听线程并触发 */
				System.out.println(bmp.getWidth() + "==" + bmp.getHeight()
						+ "==" + mapCenter.x + "==" + mapCenter.y);
				mLongPressRunnable = new LongPressedThread();
				move = false;
				mBaseHandler.postDelayed(mLongPressRunnable, LONG_PRESS_TIME);
				mLastMotionX = event.getX();
				mLastMotionY = event.getY();
				// whichItemImage(mLastMotionX, mLastMotionY);
				/** 记录起始位置 */
				start.set(event.getX(), event.getY());
				/** 记录结束位置 */
				end.set(event.getX(), event.getY());
				/** 移动模式 */
				mode = MODE.DRAG;
				break;
			/** 手指在屏幕移动，该 事件会不断地触发 */
			case MotionEvent.ACTION_MOVE:
				/** 移动后，就不需要初始化 */
				bb = false;
				/** 移动超过阈值，则表示移动了 */
				if (Math.abs(mLastMotionX - event.getX()) > TOUCH_SLOP
						|| Math.abs(mLastMotionY - event.getY()) > TOUCH_SLOP) {
					mBaseHandler.removeCallbacks(mLongPressRunnable);
				} else {
					/** 为保证移动不至于太过灵敏，如果不超过阈值，则不做任何刷新动作 */
					break;
				}
				move = true;
				System.out.println("MOVE");
				/**
				 * 需要限制在图片范围内平移
				 */
				if (mode == MODE.DRAG && imageType != IMAGE_SMALL) {
					/**
					 * 四个临界值
					 */
					int OffsetX1 = (int) (bmp.getWidth() / 2 - (mapCenter.x - start.x));
					int OffsetX2 = (int) (-bmp.getWidth() / 2 + screenCenter.x
							* 2 - mapCenter.x + start.x);
					int OffsetY1 = (int) (bmp.getHeight() / 2 - (mapCenter.y - start.y));
					int OffsetY2 = (int) (-bmp.getHeight() / 2 + screenCenter.y
							* 2 - mapCenter.y + start.y);
					
					/**
					 * 四个临界判定
					 */
					boolean OffsetX1B = mapCenter.x + (event.getX() - start.x) >= bmp
							.getWidth() / 2;
					boolean OffsetX2B = (-(mapCenter.x
							+ (event.getX() - start.x) - screenCenter.x * 2)) >= bmp
							.getWidth() / 2;
					boolean OffsetY1B = mapCenter.y + (event.getY() - start.y) >= bmp
							.getHeight() / 2;
					boolean OffsetY2B = (-(mapCenter.y
							+ (event.getY() - start.y) - screenCenter.y * 2)) >= bmp
							.getHeight() / 2;
					if (imageType == IMAGE_LARGE) {
						/** 判断是否越界，八中可能 */
						if (OffsetX1B && OffsetY1B)
							end.set(OffsetX1, OffsetY1);
						else if (OffsetX1B && OffsetY2B)
							end.set(OffsetX1, OffsetY2);
						else if (OffsetX2B && OffsetY1B)
							end.set(OffsetX2, OffsetY1);
						else if (OffsetX2B && OffsetY2B)
							end.set(OffsetX2, OffsetY2);
						else if (OffsetX1B)
							end.set(OffsetX1, event.getY());
						else if (OffsetX2B)
							end.set(OffsetX2, event.getY());
						else if (OffsetY1B)
							end.set(event.getX(), OffsetY1);
						else if (OffsetY2B)
							end.set(event.getX(), OffsetY2);
						else
							end.set(event.getX(), event.getY());
					} else if (imageType == IMAGE_HIGH) {
						if (OffsetY1B)
							end.set(start.x, OffsetY1);
						else if (OffsetY2B)
							end.set(start.x, OffsetY2);
						else if (OffsetX1B)
							end.set(start.x, event.getY());
						else if (OffsetX2B)
							end.set(start.x, event.getY());
						
						else
							end.set(event.getX(), event.getY());
					} else if (imageType == IMAGE_LONG) {

						if (OffsetX1B)
							end.set(OffsetX1, start.y);
						else if (OffsetX2B)
							end.set(OffsetX2, start.y);
						else if (OffsetY1B)
							end.set(event.getX(), start.y);
						else if (OffsetY2B)
							end.set(event.getX(), start.y);
						else
							end.set(event.getX(), event.getY());
					}
				}
				invalidate();
				break;
			/** 手指离开屏 */
			case MotionEvent.ACTION_UP:
				/** 释放了 */
				mBaseHandler.removeCallbacks(mLongPressRunnable);
				move = false;
				System.out.println("UP");
				/** 记录移动后地图中心位置(坐标点在屏幕的中心) */
				mapCenter.set(mapCenter.x + (end.x - start.x), mapCenter.y
						+ (end.y - start.y));
				break;
			case MotionEvent.ACTION_POINTER_UP:// 有手指离开屏幕,但屏幕还有触点（手指）
				mode = MODE.NONE;
				break;
			}
		}
		return true;
	}

	/**
	 * 对所画点的判断，因为图片比较小，所以在坐标点上X、Y点分别加减20dp像素，也就是在正常的情况下图片的点击区域是一个边长为40dp的正方形
	 * 因为涉及到缩放，需要乘以Scale（缩放比例）所以点击区域大小也是变的
	 */
	public void whichItemImage(float x, float y) {

		for (int i = 0; i < pointData.size(); i++) {
			float x1 = (pointData.get(i).getPointX())
					- (bmp.getWidth() / 2 - mapCenter.x);

			float x2 = (pointData.get(i).getPointX() + b.getWidth())
					- (bmp.getWidth() / 2 - mapCenter.x);
			float y1 = (pointData.get(i).getPointY())
					- (bmp.getHeight() / 2 - mapCenter.y);
			float y2 = (pointData.get(i).getPointY() + b.getHeight())
					- (bmp.getHeight() / 2 - mapCenter.y);
			System.out.println(pointData.get(i).getPointX() + "=="
					+ b.getWidth() / 2 + "==" + bmp.getWidth() / 2 + "=="
					+ mapCenter.x);
			
			Log.d(TAG, "x1========" + x1);
			Log.d(TAG, "x2========" + x2);
			Log.d(TAG, "y1========" + y1);
			Log.d(TAG, "y2========" + y2);
			Log.d(TAG, "x========" + x);
			Log.d(TAG, "y========" + y);
			Log.d(TAG, "xx========" + mapCenter.x);
			Log.d(TAG, "yy========" + mapCenter.y);
			
			if (x >= x1 && x <= x2 && y >= y1 && y <= y2) {
				// Toast.makeText(context, "index=" + i, Toast.LENGTH_SHORT)
				// .show();
			}

		}

	}

	public void setOnPanelClickListener(PanelClickListener panelClickListener) {
		this.panelClickListener = panelClickListener;
	}

}